#include "epollsever.hpp"
#include "threadpool.hpp"
#include <fcntl.h>
#include <cstdio>
static Thread_pool<string> thread;
// 设置非阻塞
bool setblock(int sock)
{
    int fl = fcntl(sock, F_GETFL);
    if (fl < 0)
        return false;
    fcntl(sock, F_SETFL, fl | O_NONBLOCK);
    return true;
}
// 读取已连接的文件描述符
void Accept(const typename std::unordered_map<int, Data_buffer *>::iterator &it, std::unordered_map<int, Data_buffer *> *buffer)
{
    while (true)
    {
        int sock = it->second->_sock_ptr->Accept();
        if (sock < 0)
            break;
        if (!setblock(sock))
        {
            cout << "setblock fail" << endl;
            cout << strerror(errno) << endl;
            return;
        }
        it->second->_epfd_ptr->Epoll_Ctl(EPOLL_CTL_ADD, sock, EPOLLIN | EPOLLET);
        Data_buffer *ptr = new Data_buffer;
        ptr->_epfd_ptr = it->second->_epfd_ptr;
        ptr->_sock = sock;
        ptr->_sock_ptr = it->second->_sock_ptr;
        buffer->emplace(std::make_pair(sock, ptr));
        cout << "连接成功" << endl;
    }
}
// 读取操作
void Recv(std::unordered_map<int, Data_buffer *> *buffer, const epoll_event events)
{
    // typename std::unordered_map<int, Data_buffer *>::iterator it = buffer->find(events.data.fd);
    auto it = buffer->find(events.data.fd);
    if (it->first == it->second->_sock_ptr->_sock)
    {
        Accept(it, buffer);
        return;
    }
    char recv_buffer[BUFFER_NUM];
    memset(recv_buffer, 0, BUFFER_NUM);
    while (true)
    {
        ssize_t s = recv(events.data.fd, recv_buffer, BUFFER_NUM, 0);
        if (s > 0)
        {
            it->second->_inbuffer += recv_buffer;
            char buffer[101];
            memset(buffer, 0, 101);
            int i = 0;
            char sign[4] = {'|', '\\', '-', '/'};
            int j = 0;
            while (i < 100)
            {
                j = j % 4;
                buffer[i++] = '#';
                printf("\r");
                printf("[%s]", buffer);
                printf("[%d]", i);
                printf("[%c]", sign[j++]);
                fflush(stdout);
                usleep(100000);
            }
            std::cout << std::endl;
        }
        else if (s == 0)
        {
            cout << "对方已经断开连接" << endl;
            it->second->_epfd_ptr->Epoll_Ctl(EPOLL_CTL_DEL, it->first, 0);
            delete it->second;
            it->second = nullptr;
            close(it->first);
            buffer->erase(it->first);
            break;
        }
        else
        {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
            {
                thread.Start(it->second->_inbuffer, it->second->_outbuffer);
                std::cout << "没数据，请再试一次" << std::endl;
                break;
            }
            else if (errno == EINTR)
            {
                std::cout << "被中断，请再试一次" << std::endl;
                continue;
            }
            else
            {
                std::cout << "recv fail:" << strerror(errno) << std::endl;
                break;
            }
        }
    }
}
// 写事件操作
void Write(std::unordered_map<int, Data_buffer *> *buffer, const epoll_event events)
{
    // const typename std::unordered_map<int, Data_buffer *>::iterator it = buffer->find(events.data.fd);
    auto it = buffer->find(events.data.fd);
    while (true)
    {
        ssize_t s = send(it->first, it->second->_outbuffer.c_str(), it->second->_outbuffer.size(), 0);
        if (s > 0)
        {
            cout << it->second->_outbuffer.c_str() << endl;
            it->second->_outbuffer.clear();
        }
        else
        {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
            {
                cout << "os buffer full or not data" << endl;
                break;
            }
            else if (errno == EINTR)
            {
                cout << "try again..." << endl;
                continue;
            }
            else
            {
                cout << "send fail:" << strerror(errno) << endl;
                break;
            }
        }
    }
}
// 处理时间操作
void Handle(int num, std::unordered_map<int, Data_buffer *> *buffer, const epoll_event *events)
{
    for (int i = 0; i < num; i++)
    {
        if (buffer->find(events[i].data.fd) == buffer->end())
        {
            cout << "hash not this sock" << events[i].data.fd << strerror(errno) << endl;
            break;
        }
        if (events[i].events & EPOLLIN)
            Recv(buffer, events[i]);
        if (events[i].events & EPOLLOUT)
            Write(buffer, events[i]);
    }
}

// 网络加载进度条
// int main()
// {
//     char buffer[101];
//     memset(buffer, 0, 101);
//     int i = 0;
//     char sign[4] = {'|', '\\', '-', '/'};
//     int j = 0;
//     while (i < 100)
//     {
//         j = j % 4;
//         buffer[i++] = '#';
//         printf("\r");
//         printf("[%s]", buffer);
//         printf("[%d]", i);
//         printf("[%c]", sign[j++]);
//         fflush(stdout);
//         usleep(100000);
//     }
//     std::cout << std::endl;
//     return 0;
// }